package com.fit.piris.services;

import java.io.IOException;

import org.apache.tapestry5.*;
import org.apache.tapestry5.hibernate.HibernateTransactionAdvisor;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.MethodAdviceReceiver;
import org.apache.tapestry5.ioc.OrderedConfiguration;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.Contribute;
import org.apache.tapestry5.ioc.annotations.Local;
import org.apache.tapestry5.ioc.annotations.Match;
import org.apache.tapestry5.services.ComponentRequestFilter;
import org.apache.tapestry5.services.ComponentRequestHandler;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.RequestFilter;
import org.apache.tapestry5.services.RequestHandler;
import org.apache.tapestry5.services.Response;
import org.apache.tapestry5.validator.ValidatorMacro;
import org.slf4j.Logger;

import com.fit.piris.dao.fanpage.FanPageDAO;
import com.fit.piris.dao.fanpage.FanPageDAOImpl;
import com.fit.piris.dao.message.MessageDAO;
import com.fit.piris.dao.message.MessageDAOImpl;
import com.fit.piris.dao.message.priority.MessagePriorityDAO;
import com.fit.piris.dao.message.priority.MessagePriorityDAOImpl;
import com.fit.piris.dao.user.UserDAO;
import com.fit.piris.dao.user.UserDAOImpl;
import com.fit.piris.dao.user.fanpage.UserFanPageDAO;
import com.fit.piris.dao.user.fanpage.UserFanPageDAOImpl;
import com.fit.piris.security.AuthenticationFilter;

/**
 * This module is automatically included as part of the Tapestry IoC Registry, it's a good place to
 * configure and extend Tapestry, or to place your own service definitions.
 */
public class AppModule
{
    public static void bind(ServiceBinder binder)
    {
        // binder.bind(MyServiceInterface.class, MyServiceImpl.class);
        
        // Make bind() calls on the binder object to define most IoC services.
        // Use service builder methods (example below) when the implementation
        // is provided inline, or requires more initialization than simply
        // invoking the constructor.
    	binder.bind(Authenticator.class, BasicAuthenticator.class);
    	binder.bind(UserDAO.class, UserDAOImpl.class);
    	binder.bind(MessageDAO.class, MessageDAOImpl.class);
    	binder.bind(MessagePriorityDAO.class, MessagePriorityDAOImpl.class);
    	binder.bind(FanPageDAO.class,FanPageDAOImpl.class);
    	binder.bind(UserFanPageDAO.class,UserFanPageDAOImpl.class);
    }
    
    
    public static void contributeApplicationDefaults(
            MappedConfiguration<String, String> configuration)
    {
        // Contributions to ApplicationDefaults will override any contributions to
        // FactoryDefaults (with the same key). Here we're restricting the supported
        // locales to just "en" (English). As you add localised message catalogs and other assets,
        // you can extend this list of locales (it's a comma separated series of locale names;
        // the first locale name is the default when there's no reasonable match).
        
        configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");

        // The factory default is true but during the early stages of an application
        // overriding to false is a good idea. In addition, this is often overridden
        // on the command line as -Dtapestry.production-mode=false
        configuration.add(SymbolConstants.PRODUCTION_MODE, "false");

        // The application version number is incorprated into URLs for some
        // assets. Web browsers will cache assets because of the far future expires
        // header. If existing assets are changed, the version number should also
        // change, to force the browser to download new versions.
        configuration.add(SymbolConstants.APPLICATION_VERSION, "1.0-SNAPSHOT");
    }
    
    @Match("*DAO")
	public static void adviseTransactions(HibernateTransactionAdvisor advisor,
			MethodAdviceReceiver receiver) {
		advisor.addTransactionCommitAdvice(receiver);
	}
    
    @Contribute(ValidatorMacro.class)
   	public static void combineValidators(
   			MappedConfiguration<String, String> configuration) {
   		configuration.add("username", "required, minlength=3, maxlength=20");
   		configuration.add("password", "required, minlength=6, maxlength=20");
   	}

   	@Contribute(ComponentRequestHandler.class)
   	public static void contributeComponentRequestHandler(
   			OrderedConfiguration<ComponentRequestFilter> configuration) {
   		configuration.addInstance("RequiresLogin", AuthenticationFilter.class);
   	}
}
